package com.smartwrite.service;

import com.smartwrite.entity.TaskInfo;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.smartwrite.enums.TaskStatus;
import jakarta.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 任务存储服务
 * 负责任务信息的存储、检索和持久化
 */
@Service
public class TaskStorageService {

    // 内存中的任务存储
    private final Map<String, TaskInfo> taskStorage = new ConcurrentHashMap<>();

    // 结果目录路径
    @Value("${smartwrite.results.dir:${user.home}/smartwrite/results}")
    private String resultsDir;

    private final ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 初始化服务，创建结果目录并加载已有任务
     */
    @PostConstruct
    public void init() {
        try {
            // 创建结果目录
            Path resultPath = Paths.get(resultsDir);
            if (!Files.exists(resultPath)) {
                Files.createDirectories(resultPath);
            }

            // 重新加载已有任务
            reloadTaskStorage();

        } catch (IOException e) {
            throw new RuntimeException("初始化任务存储服务失败: " + e.getMessage(), e);
        }
    }

    /**
     * 存储任务信息
     */
    public void storeTask(TaskInfo taskInfo) {
        if (taskInfo == null || taskInfo.getTaskId() == null) {
            throw new IllegalArgumentException("任务信息或任务ID不能为空");
        }

        // 设置任务目录
        String taskDir = Paths.get(resultsDir, taskInfo.getTaskId()).toString();
        taskInfo.setTaskDir(taskDir);

        // 创建任务目录
        try {
            Files.createDirectories(Paths.get(taskDir));
            Files.createDirectories(Paths.get(taskDir, "records"));
        } catch (IOException e) {
            throw new RuntimeException("创建任务目录失败: " + e.getMessage(), e);
        }

        // 存储到内存
        taskStorage.put(taskInfo.getTaskId(), taskInfo);

        // 持久化任务信息
        persistTaskInfo(taskInfo);
    }

    /**
     * 获取任务信息
     */
    public TaskInfo getTask(String taskId) {
        if (taskId == null) {
            return null;
        }

        // 先从内存中查找
        TaskInfo taskInfo = taskStorage.get(taskId);
        if (taskInfo != null) {
            return taskInfo;
        }

        // 如果内存中没有，尝试从文件系统加载
        return loadTaskFromDisk(taskId);
    }

    /**
     * 更新任务状态
     */
    public void updateTaskStatus(String taskId, String status) {
        TaskInfo taskInfo = getTask(taskId);
        if (taskInfo != null) {
            // 将字符串状态转换为TaskStatus枚举
            TaskStatus taskStatus = TaskStatus.fromCode(status);
            taskInfo.setStatus(taskStatus);
            persistTaskInfo(taskInfo);
        }
    }

    /**
     * 更新任务结果
     */
    public void updateTaskResult(String taskId, String result) {
        TaskInfo taskInfo = getTask(taskId);
        if (taskInfo != null) {
            taskInfo.setResult(result);
            taskInfo.setStatus(TaskStatus.COMPLETED);
            persistTaskInfo(taskInfo);
        }
    }

    /**
     * 更新任务错误信息
     */
    public void updateTaskError(String taskId, String error) {
        TaskInfo taskInfo = getTask(taskId);
        if (taskInfo != null) {
            taskInfo.setError(error);
            taskInfo.setStatus(TaskStatus.ERROR);
            persistTaskInfo(taskInfo);
        }
    }

    /**
     * 获取所有任务
     */
    public List<TaskInfo> getAllTasks() {
        return new ArrayList<>(taskStorage.values());
    }

    /**
     * 获取指定状态的任务
     */
    public List<TaskInfo> getTasksByStatus(TaskStatus status) {
        return taskStorage.values().stream()
                .filter(task -> status.equals(task.getStatus()))
                .collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
    }

    /**
     * 获取指定状态的任务（字符串版本，用于向后兼容）
     */
    public List<TaskInfo> getTasksByStatus(String status) {
        TaskStatus taskStatus = TaskStatus.fromCode(status);
        return getTasksByStatus(taskStatus);
    }

    /**
     * 删除任务
     */
    public boolean deleteTask(String taskId) {
        TaskInfo taskInfo = taskStorage.remove(taskId);
        if (taskInfo != null) {
            // 删除任务目录
            try {
                Path taskPath = Paths.get(taskInfo.getTaskDir());
                if (Files.exists(taskPath)) {
                    deleteDirectory(taskPath.toFile());
                }
                return true;
            } catch (Exception e) {
                // 记录错误但不抛出异常
                System.err.println("删除任务目录失败: " + e.getMessage());
                return false;
            }
        }
        return false;
    }

    /**
     * 停止任务
     */
    public boolean stopTask(String taskId) {
        TaskInfo taskInfo = getTask(taskId);
        if (taskInfo != null && taskInfo.isRunning()) {
            taskInfo.setStatus(TaskStatus.STOPPED);
            updateTask(taskInfo);

            // 停止进程
            Process process = taskInfo.getProcess();
            if (process != null && process.isAlive()) {
                process.destroyForcibly();
            }

            return true;
        }
        return false;
    }

    /**
     * 重新加载任务存储
     */
    private void reloadTaskStorage() {
        try {
            File resultsDirectory = new File(resultsDir);
            if (!resultsDirectory.exists() || !resultsDirectory.isDirectory()) {
                return;
            }

            File[] taskDirs = resultsDirectory.listFiles(File::isDirectory);
            if (taskDirs == null) {
                return;
            }

            for (File taskDir : taskDirs) {
                String taskId = taskDir.getName();
                TaskInfo taskInfo = loadTaskFromDisk(taskId);
                if (taskInfo != null) {
                    taskStorage.put(taskId, taskInfo);
                }
            }

        } catch (Exception e) {
            System.err.println("重新加载任务存储失败: " + e.getMessage());
        }
    }

    /**
     * 从磁盘加载任务信息
     */
    private TaskInfo loadTaskFromDisk(String taskId) {
        try {
            Path taskDir = Paths.get(resultsDir, taskId);
            if (!Files.exists(taskDir)) {
                return null;
            }

            // 加载任务信息文件
            Path taskInfoFile = taskDir.resolve("task-info.json");
            if (Files.exists(taskInfoFile)) {
                String content = Files.readString(taskInfoFile);
                TaskInfo taskInfo = objectMapper.readValue(content, TaskInfo.class);
                taskInfo.setTaskDir(taskDir.toString());

                // 检查任务状态
                Path doneFile = taskDir.resolve("done.txt");
                Path resultFile = taskDir.resolve("result.jsonl");

                if (Files.exists(doneFile)) {
                    taskInfo.setStatus(TaskStatus.COMPLETED);
                    // 加载结果
                    if (Files.exists(resultFile)) {
                        String resultContent = Files.readString(resultFile);
                        // 解析JSONL格式的结果
                        if (!resultContent.trim().isEmpty()) {
                            Map<String, Object> resultMap = objectMapper.readValue(resultContent, Map.class);
                            taskInfo.setResult((String) resultMap.get("result"));
                        }
                    }
                } else if (Files.exists(resultFile)) {
                    taskInfo.setStatus(TaskStatus.RUNNING);
                } else {
                    taskInfo.setStatus(TaskStatus.PENDING);
                }

                return taskInfo;
            }

        } catch (Exception e) {
            System.err.println("从磁盘加载任务失败 [" + taskId + "]: " + e.getMessage());
        }

        return null;
    }

    /**
     * 持久化任务信息
     */
    private void persistTaskInfo(TaskInfo taskInfo) {
        try {
            Path taskInfoFile = Paths.get(taskInfo.getTaskDir(), "task-info.json");
            String content = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(taskInfo);
            Files.writeString(taskInfoFile, content);
        } catch (Exception e) {
            System.err.println("持久化任务信息失败 [" + taskInfo.getTaskId() + "]: " + e.getMessage());
        }
    }

    /**
     * 递归删除目录
     */
    private void deleteDirectory(File directory) {
        if (directory.exists()) {
            File[] files = directory.listFiles();
            if (files != null) {
                for (File file : files) {
                    if (file.isDirectory()) {
                        deleteDirectory(file);
                    } else {
                        file.delete();
                    }
                }
            }
            directory.delete();
        }
    }

    /**
     * 获取结果目录路径
     */
    public String getResultsDir() {
        return resultsDir;
    }


    /**
     * 创建任务（别名方法，调用storeTask）
     */
    public void createTask(TaskInfo taskInfo) {
        storeTask(taskInfo);
    }

    /**
     * 更新任务信息
     */
    public void updateTask(TaskInfo taskInfo) {
        if (taskInfo == null || taskInfo.getTaskId() == null) {
            throw new IllegalArgumentException("任务信息或任务ID不能为空");
        }

        // 更新内存中的任务信息
        taskStorage.put(taskInfo.getTaskId(), taskInfo);

        // 持久化任务信息
        persistTaskInfo(taskInfo);
    }
}